﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Diagnostics;
using WCFServiceWebRole1.Models;

namespace WCFServiceWebRole1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {

        private azzModelContainer1 db = new azzModelContainer1();


        public bool validateUser(string name, string password)
        {
            try
            {
                User u = db.UserSet.Single(c => c.Name.Equals(name));
                if (u.Password.Equals(password))
                {
                    return true;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return false;
        }


        public bool addUser(string name, string password, int role, string username)
        {
            try
            {
                if (db.UserSet.Where(u => u.Name.Equals(name)).Count() == 0)
                {
                    User user = new User();
                    user.Name = name;
                    user.Password = password;
                    user.Role = role;
                    user.Username = username;
                    user.Pay = 0;

                    db.UserSet.Add(user);
                    db.SaveChanges();
                    return true;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                
            }
            return false;
        }

        public List<UserUI> getUsers()
        {
            try
            {
                List<UserUI> users = new List<UserUI>();
                foreach (User u in db.UserSet.ToList())
                {
                    UserUI userUI = new UserUI();
                    userUI.id = u.Id;
                    userUI.name = u.Name;
                    userUI.pay = u.Pay;
                    userUI.role = u.Role;

                    users.Add(userUI);
                }

                return users;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        /*public void addUser()
        {
            User u = new User();
            u.name = "Kalle";
            u.username = "StigHelmer";
            u.role = 0;
            u.password = "test";
            db.User.Add(u);
            db.SaveChanges();

        }*/

        public UserUI getUser(string userName)
        {
            try
            {


                User user = db.UserSet.Single(u => u.Username.Equals(userName));

                UserUI userUI = new UserUI();
                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in user.TimeReport)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.Name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Equals(user)).Id;

                    tempReport.end = report.Start;
                    tempReport.start = report.Start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }
                userUI.pay = user.Pay;
                userUI.name = user.Name;
                userUI.id = user.Id;
                userUI.role = user.Role;
                
                userUI.timeReports = timereports;
                return userUI;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        public UserUI getUserById(int userId)
        {

            try
            {
                User user = db.UserSet.Single(u => u.Id.Equals(userId));

                UserUI userUI = new UserUI();
                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in user.TimeReport)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.Name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Equals(user)).Id;

                    tempReport.end = report.Stop;
                    tempReport.start = report.Start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }
                userUI.pay = user.Pay;
                userUI.name = user.Name;
                userUI.id = user.Id;
                userUI.role = user.Role;
                
                userUI.timeReports = timereports;
                return userUI;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        public List<TimeReportUI> getTimeReportsForUserBetweenDatesById(int userId, DateTime start, DateTime stop)
        {
            try
            {
                List<TimeReport> reports = db.TimeReportSet.Where(report => report.User.Id.Equals(userId) &&
                    (((report.Start < stop) && (report.Stop >= start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.Id = report.Project.Id;
                    tempProject.name = report.Project.Name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Id.Equals(userId)).Id;

                    tempReport.end = report.Stop;
                    tempReport.start = report.Start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }

                return timereports;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        public List<TimeReportUI> getTimeReportsForProjectBetweenDates(int projectId, DateTime start, DateTime stop)
        {
            try
            {
                List<TimeReport> reports = db.TimeReportSet.Where(report => report.Project.Id.Equals(projectId) &&
                    (((report.Start < stop) && (report.Stop >= start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.Name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Id.Equals(projectId)).Id;

                    tempReport.end = report.Stop;
                    tempReport.start = report.Start;
                    if (tempReport.start < start)
                    {
                        tempReport.start = start;
                    }
                    if (tempReport.end > stop)
                    {
                        tempReport.end = stop;
                    }
                    tempReport.description = report.Description;
                    tempReport.project = tempProject;
                    tempReport.user = new UserUI() { id = report.User.Id, name = report.User.Name, pay = report.User.Pay };

                    timereports.Add(tempReport);

                }

                return timereports;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        //Robin addat
        public List<TimeReportUI> getTimeReportsForUserInProjectBetweenDates(int userId, int projectId, DateTime start, DateTime stop)
        {
            try
            {
                List<TimeReport> reports = db.TimeReportSet.Where(report => report.Project.Id.Equals(projectId) && report.User.Id.Equals(userId) &&
                    (((report.Start < stop) && (report.Stop >= start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.Name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Id.Equals(projectId)).Id;

                    tempReport.end = report.Stop;
                    tempReport.start = report.Start;
                    if (tempReport.start < start)
                    {
                        tempReport.start = start;
                    }
                    if (tempReport.end > stop)
                    {
                        tempReport.end = stop;
                    }
                    tempReport.project = tempProject;
                    tempReport.user = new UserUI() { id = report.User.Id, name = report.User.Name, pay = report.User.Pay };

                    timereports.Add(tempReport);

                }

                return timereports;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }


        public List<TimeReportUI> getTimeReportsForUserBetweenDatesByName(string userName, DateTime start, DateTime stop)
        {
            try
            {
                List<TimeReport> reports = db.TimeReportSet.Where(report => report.User.Username.Equals(userName) &&
                    (((report.Start < stop) && (report.Stop >= start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.Name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Username.Equals(userName)).Id;

                    tempReport.end = report.Stop;
                    tempReport.start = report.Start;
                    if (tempReport.start < start)
                    {
                        tempReport.start = start;
                    }
                    if (tempReport.end > stop)
                    {
                        tempReport.end = stop;
                    }

                    tempReport.project = tempProject;
                    tempReport.description = report.Description;
                    tempReport.user = new UserUI() { id = report.User.Id, name = report.User.Name, pay = report.User.Pay, role = report.User.Role };

                    timereports.Add(tempReport);

                }

                return timereports;

            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null; ;
            }
        }

        public TimeSpanUI getTimeSpentOnProjectByUserBetweenDates(int userId, int projectId, DateTime start, DateTime end)
        {
            try
            {
                TimeSpanUI span = new TimeSpanUI();

                List<TimeReport> reports = db.TimeReportSet.Where(report => report.User.Id.Equals(userId) && report.Project.Id.Equals(projectId) &&
                    (((report.Start < end) && (report.Start >= start)) || ((report.Stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();
                TimeSpan total = new TimeSpan();

                foreach (TimeReport report in reports)
                {
                    if (report.Stop <= end && report.Start >= start)
                    {
                        total += report.Stop.Subtract(report.Start);
                    }
                    else if (report.Stop > end && report.Start >= start)
                    {
                        total += end.Subtract(report.Start);
                    }
                    else if (report.Stop > end && report.Start < start)
                    {
                        total += end.Subtract(start);
                    }
                    else if (report.Stop <= end && report.Start < start)
                    {
                        total += report.Stop.Subtract(start);
                    }

                }
                span.Hours = total.Hours;
                span.Minutes = total.Minutes;

                return span;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        public TimeSpanUI getTimeSpentOnProjectBetweenDates(int projectId, DateTime start, DateTime end)
        {
            try
            {
                TimeSpanUI span = new TimeSpanUI();

                List<TimeReport> reports = db.TimeReportSet.Where(report => report.Project.Id.Equals(projectId) &&
                    (((report.Start < end) && (report.Start >= start)) || ((report.Stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();
                TimeSpan total = new TimeSpan();

                foreach (TimeReport report in reports)
                {
                    if (report.Stop <= end && report.Start >= start)
                    {
                        total += report.Stop.Subtract(report.Start);
                    }
                    else if (report.Stop > end && report.Start >= start)
                    {
                        total += end.Subtract(report.Start);
                    }
                    else if (report.Stop > end && report.Start < start)
                    {
                        total += end.Subtract(start);
                    }
                    else if (report.Stop <= end && report.Start < start)
                    {
                        total += report.Stop.Subtract(start);
                    }

                }
                span.Hours = total.Hours;
                span.Minutes = total.Minutes;

                return span;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        public List<UserUI> getUsersInvolvedInProjectWithRole(int projectId, int role)
        {
            List<UserUI> users = new List<UserUI>();
            try
            {
                List<UserRole> roleList = db.UserRoleSet.Where(roles => roles.Project.Id.Equals(projectId) && roles.Role.Equals(role)).ToList();
                

                foreach (UserRole tempRole in roleList)
                {

                    UserUI user = new UserUI();
                    user.id = tempRole.User.Id;
                    user.name = tempRole.User.Name;
                    user.pay = tempRole.User.Pay;

                    users.Add(user);
                }

                return users;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                
            }
            return users;
        }

        public bool addTimeReport(int projectId, int userId, DateTime start, DateTime stop, string description)
        {
            try
            {
                TimeReport report = new TimeReport();
                report.Project = db.ProjectSet.Where(project => project.Id.Equals(projectId)).Single();
                report.Start = start;
                report.Stop = stop;
                report.User = db.UserSet.Where(user => user.Id.Equals(userId)).Single();
                report.Description = description;

                report.User.TimeReport.Add(report);
                report.Project.TimeReport.Add(report);

                db.TimeReportSet.Add(report);
                db.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return false;
            }
        }

        public List<ProjectUI> getProjectsWithUserInRole(int role, int userId)
        {
            try
            {
                List<UserRole> rolesList = db.UserRoleSet.Where(roles => roles.User.Id.Equals(userId) && roles.Role.Equals(role)).ToList();
                List<ProjectUI> projects = new List<ProjectUI>();

                foreach (UserRole tempRole in rolesList)
                {
                    ProjectUI tempProject = new ProjectUI();
                    tempProject.Id = tempRole.Project.Id;
                    tempProject.name = tempRole.Project.Name;
                    tempProject.description = tempRole.Project.Description;

                    projects.Add(tempProject);
                }
                return projects;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }
        }

        public bool addUserRoleInProject(int userId, int projectId, int role)
        {
            try
            {
                if (db.UserRoleSet.Where(userRole => userRole.Project.Id.Equals(projectId) && userRole.Role.Equals(role) && userRole.User.Id.Equals(userId)).Count() == 0)
                {
                    UserRole userRole = new UserRole();
                    userRole.Project = db.ProjectSet.Where(project => project.Id.Equals(projectId)).Single();
                    userRole.Role = role;
                    userRole.User = db.UserSet.Where(user => user.Id.Equals(userId)).Single();

                    db.UserRoleSet.Add(userRole);
                    db.SaveChanges();
                    return true;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
               
            }
            return false;
        }

        public bool addProject(string name, string description)
        {
            try
            {
                Project project = new Project();
                project.Name = name;
                project.TimeReport = new List<TimeReport>();
                project.UserRole = new List<UserRole>();
                project.Description = description;
                db.ProjectSet.Add(project);
                db.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return false;
            }
        }

        //Robin addat
        public bool addUserToProject(string username, string projectname, int role)
        {
            try
            {
                UserRole userRole = new UserRole();
                userRole.Project = db.ProjectSet.Where(project => project.Name.Equals(projectname)).Single();
                userRole.Role = role;
                userRole.User = db.UserSet.Where(user => user.Name.Equals(username)).Single();

                db.UserRoleSet.Add(userRole);
                db.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return false;
            }
        }

        //Robin addat
        public List<ProjectUI> getAllUsersProjects(int userId)
        {
            List<ProjectUI> projects = new List<ProjectUI>();
            try
            {
                User u = db.UserSet.Single(user => user.Id.Equals(userId));
                foreach (UserRole ur in u.UserRole.Where(r => r.User.Id.Equals(u.Id)))
                {
                    projects.Add(new ProjectUI() { Id = ur.Project.Id, name = ur.Project.Name, role = ur.Role });
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return projects;
        }

        public List<ProjectUI> getAllProjects()
        {
            List<ProjectUI> projects = new List<ProjectUI>();
            try
            {
                List<Project> list = db.ProjectSet.ToList();

                foreach (Project p in list)
                {
                    projects.Add(new ProjectUI() { Id = p.Id, name = p.Name });
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return projects;

        }

        public bool editUser(int userId, int pay, int role)
        {
            try
            {
                User user = db.UserSet.Single(u => u.Id.Equals(userId));
                user.Pay = pay;
                user.Role = role;
                db.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            return false;
        }

        public List<UserUI> getCustomers()
        {
            List<UserUI> users = new List<UserUI>();
            List<User> u = db.UserSet.Where(user => user.Role.Equals(1)).ToList();

            foreach(User user in u){
                users.Add(new UserUI() { id = user.Id, name = user.Name, role = user.Role });
            }
            return users;
        }

        public ProjectUI getProject(int projectId)
        {
            try
            {
                ProjectUI project = new ProjectUI();
                Project p = db.ProjectSet.Single(pro => pro.Id.Equals(projectId));

                project.Id = p.Id;
                project.name = p.Name;
                project.description = p.Description;
                return project;

            }
            catch (Exception e)
            {
                return null;
            }
        }

        public string GetData(int value)
        {
            /*
            try
            {
                azzModelContainer1 db = new azzModelContainer1();
                db.UserSet.Add(new User() {Name = "robin", Password="A", Username="robin", Role = 2, Pay = 100 });
                db.SaveChanges();
                return string.Format("You entered: {0}", value);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return "lol";
            }
            */
            return "5";
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
}
